#ifndef JIONOTIFIER
#define JIONOTIFIER

#include <JXQCore/JXQGlobal>
#include <JXQCore/JMessage>
#include <JXQCore/JFlags>

namespace JXQ
{

class ListenThread;
class JMultiIONotifier;
class JIONotifierPrivate;

class JXQLIB_EXPORT JIONotifier
{
public:
	enum TypeFlag
	{
		Read  = 0x01,
		Write = 0x02
	};
	J_DECLARE_FLAGS(Type, TypeFlag)

	J_MESSAGE(ready, int, Type)

public:
	explicit JIONotifier(int descriptor, Type type = Read);
	virtual ~JIONotifier();

public:
	int descriptor() const;
	Type type() const;

public:
	// Does not close by default.
	void setCloseOnDelete(bool enable = true);
	bool closeOnDelete() const;

protected:
	virtual void event(Type type);

private:
	friend class ListenThread;
	friend class JMultiIONotifier;
	JIONotifierPrivate *d_ptr;
};

class JMultiIONotifierPrivate;

// 多路复用
class JXQLIB_EXPORT JMultiIONotifier
{
	J_MESSAGE(ready, int, JIONotifier::Type)

public:
	JMultiIONotifier();
	virtual ~JMultiIONotifier();

public:
	/*
		default: auto delete
		Call setDeleteOnUnregister(bool) to setting.
	*/
	void registerDescriptor(JIONotifier *notifier);
	void registerDescriptor(int descriptor, JIONotifier::Type type = JIONotifier::Read);

	void unregisterDescriptor(int descriptor);
	void unregisterDescriptor(JIONotifier *notifier);
	void unregisterAll();

public:
	void setDeleteOnUnregister(bool enable = true);
	bool deleteOnUnregister() const;

protected:
	virtual void event(int descriptor, JIONotifier::Type type);

private:
	friend class JMultiIONotifierPrivate;
	JMultiIONotifierPrivate *d_ptr;
};

} //namespace JXQ

J_DECLARE_OPERATORS_FOR_FLAGS(JXQ::JIONotifier::Type)


#endif //JIONOTIFIER
